import { Ref, shallowRef } from "vue"
import { RequestConfigExtra, ResponseBodyError } from "./types"
import { isUndefined } from "@/utils"
import { http } from "./axios"

export interface FetchResult {
    res: Ref<any>
    error: Ref<ResponseBodyError>
    isOk: () => boolean
}

async function useFetch(api: () => Promise<any>): Promise<FetchResult> {
    const responseRef = shallowRef<any>()
    const errorRef = shallowRef<any>()

    try {
        const { data, status, message } = await api()
        if (status === true) {
            responseRef.value = data
            errorRef.value = undefined
        } else {
            responseRef.value = undefined
            errorRef.value = message
        }
    } catch (e) {
        responseRef.value = undefined
        errorRef.value = e
    }

    const isOk = () => isUndefined(errorRef.value)
    return { res: responseRef, error: errorRef, isOk }
}

const useGet = async (url: string, params?: any, options?: RequestConfigExtra) => useFetch(() => http.get(url, params, options))
const usePost = (url: string, params?: any, options?: RequestConfigExtra) => useFetch(() => http.post(url, params, options))
const useDelete = (url: string, params?: any, options?: RequestConfigExtra) => useFetch(() => http.delete(url, params, options))
const usePut = (url: string, params?: any, options?: RequestConfigExtra) => useFetch(() => http.put(url, params, options))

export * from "./types"
export { useGet, usePost, useDelete, usePut }
